﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Hive.Core.Model
{
    /// <summary>
    /// Abstract base class for configuration objects.
    /// </summary>
    public abstract class Configuration
    {
        /// <summary>
        /// Creates a configuration.
        /// </summary>
        protected Configuration()
        {
        }

        /// <summary>
        /// Creates a configuration from a descriptor.
        /// </summary>
        /// <param name="descriptor">The descriptor.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="descriptor"/> is null.</exception>
        protected Configuration(Descriptor descriptor)
        {
            if (descriptor == null)
                throw new ArgumentNullException("descriptor");
        }

        /// <summary>
        /// Converts the configuration object to a descriptor.
        /// </summary>
        /// <returns>The binary repository descriptor.</returns>
        public Descriptor ToDescriptor()
        {
            var descriptor = new Descriptor();
            PopulateDescriptor(descriptor);
            return descriptor;
        }

        /// <summary>
        /// Populates the descriptor.
        /// </summary>
        /// <param name="descriptor">The descriptor to populate, not null.</param>
        protected virtual void PopulateDescriptor(Descriptor descriptor)
        {
        }

        /// <summary>
        /// Makes a deep copy of the configuration.
        /// </summary>
        /// <returns>The new copy.</returns>
        public Configuration Copy()
        {
            return CreateInstanceOfSameType(ToDescriptor());
        }

        /// <summary>
        /// Creates a new instance of the same type from a descriptor.
        /// </summary>
        /// <param name="descriptor">The descriptor, not null.</param>
        /// <returns>The new instance.</returns>
        protected abstract Configuration CreateInstanceOfSameType(Descriptor descriptor);
    }
}
